﻿@inherits LayoutComponentBase
@implements IDisposable
@namespace BootstrapBlazor.Components
@using AdminBlazor.Infrastructure.Encrypt
@using Microsoft.AspNetCore.Http
@using Microsoft.AspNetCore.Http.Extensions

<div class="app-wrapper">

    <nav class="app-header navbar navbar-expand bg-body">
        <div class="container-fluid">
            <ul class="navbar-nav">
                <li class="nav-item">
                    <a class="nav-link" href="#" role="button" onclick="adminBlazorJS.sidebarToggle();return false;">
                        <i class="fa fa-bars"></i>
                    </a>
                </li>
                @if (login.CurrentMenu != null)
                {
                    <li class="nav-item d-none d-md-block ml-3" style="line-height:1rem;margin-top:12px">
                        <ol class="breadcrumb float-sm-end m-0 p-0">
                            <li class="breadcrumb-item">首页</li>
                            @if (login.CurrentMenu.Parent != null)
                            {
                                <li class="breadcrumb-item">@login.CurrentMenu.Parent.Label</li>
                            }
                            <li class="breadcrumb-item active" aria-current="page">@login.CurrentMenu?.Label</li>
                        </ol>
                    </li>
                }
            </ul>
            @if (login?.User != null)
            {
                <Logout ImageUrl="logo.png" DisplayName="@login.User.Username" UserName="@login.Roles.FirstOrDefault()?.Name" class="">
                    <HeaderTemplate>
                        <div class="d-flex flex-fill align-items-center">
                            <img alt="avatar" src="logo.png" style="border-radius: 50%;">
                            <div class="flex-fill">
                                <div class="logout-dn">@login.User.Username</div>
                                <div class="logout-un">@login.Roles.FirstOrDefault()?.Description</div>
                            </div>
                        </div>
                    </HeaderTemplate>
                    <LinkTemplate>
                        <a @onclick="LogoutClick" href="@AdminBlazorOptions.Global_BaseUrl/Login"><i class="fa-solid fa-key"></i><span>注销</span></a>
                    </LinkTemplate>
                </Logout>
            }
        </div>
    </nav>

    <aside class="app-sidebar bg-body-secondary shadow" data-bs-theme="dark">
        <div class="sidebar-brand">
            <a href="@AdminBlazorOptions.Global_BaseUrl" class="brand-link">
                <img src="logo.png" class="brand-image opacity-75 shadow">
                <span class="brand-text fw-light">@AdminBlazorOptions.Global_Title</span>
            </a>
        </div>
        <div class="sidebar-wrapper">
            <AdminSidebarMenu />
        </div>
    </aside>

    <main class="app-main">
@*         <div class="app-content-header">
            <div class="container-fluid">
                <div class="row">
                    <div class="col-sm-6">
                        <h3 class="mb-0"></h3>
                    </div>
                    <div class="col-sm-6">
                        <ol class="breadcrumb float-sm-end">
                            <li class="breadcrumb-item"><a href="#">Home</a></li>
                            <li class="breadcrumb-item active" aria-current="page">
                            </li>
                        </ol>
                    </div>
                </div>
            </div>
        </div> *@
        <div class="app-content mt-3">
            @if (login.AuthPathSuccess)
            {
                @Body
            }
        </div>
    </main>


    @* <footer class="app-footer">
        <div class="float-end d-none d-sm-inline"></div>
        <strong>
            Copyright &copy; 2024-2024&nbsp;
            <a href="https://freesql.net" class="text-decoration-none">FreeSql.net</a>.
        </strong>
        All rights reserved.
    </footer> *@
</div>

@code {
    [CascadingParameter, Inject] AdminLoginInfo login { get; set; }
    [Inject] IHttpContextAccessor httpContextAccessor { get; set; }

    void LogoutClick()
    {
        nav.NavigateTo($"{AdminBlazorOptions.Global_BaseUrl}/Login?LogoutToken={DesEncrypt.Encrypt("logout$$" + login.User.Username).UrlEncode()}", true);
    }

    async protected override Task OnInitializedAsync()
    {
        var context = httpContextAccessor.HttpContext;
        var cookie = context.Request.Cookies["login"];

        login.Service = context.RequestServices;
        if (!cookie.IsNull())
        {
            if (AdminLoginInfo.TryParseCookie(context.Request.Cookies["login"], out var userId, out var loginTime) && userId > 0)
                login.User = await fsql.Select<UserEntity>().Where(a => a.Id == userId).FirstAsync();
            else
                context.Response.Cookies.Delete("login");

            if (login.User != null && login.User.LoginTime.Subtract(loginTime).TotalSeconds != 0)
            {
                //被其他端登陆挤出
                login.User = null;
                context.Response.Cookies.Delete("login");
                context.Response.Redirect($"{AdminBlazorOptions.Global_BaseUrl}/Login?Redirect={context.Request.GetEncodedPathAndQuery().UrlEncode()}");
                return;
            }
        }

        if (!await login.AuthPath(new Uri(nav.Uri).AbsolutePath))
        {
            if (login.User != null)
            {
                //context.Response.StatusCode = 403;
                //await context.Response.WriteAsync("没有访问权限.");
            }
            else
            {
                context.Response.Redirect($"{AdminBlazorOptions.Global_BaseUrl}/Login?Redirect={context.Request.GetEncodedPathAndQuery().UrlEncode()}");
                return;
            }
        }
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (!firstRender) return;
        if (login.Roles?.Any() == false) await JS.Error("没有访问权限: 未分配角色.");
        else if (!login.AuthPathSuccess) await JS.Error("没有访问权限.");

        locationChangingHandler = nav.RegisterLocationChangingHandler(async e =>
        {
            var uri = nav.ToAbsoluteUri(e.TargetLocation);
            if (!await login.AuthPath(uri.AbsolutePath))
                await JS.Error("没有访问权限.");
        });
    }

    IDisposable locationChangingHandler;
    public void Dispose() => locationChangingHandler?.Dispose();
}